package com.internetCafes.spms.web.customer.bizservice.impl.customer;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.internetCafes.spms.common.utils.ShiroUtils;
import com.internetCafes.spms.core.exception.RRException;
import com.internetCafes.spms.core.exception.RRExceptionCodeEnum;
import com.internetCafes.spms.web.customer.bizservice.customer.IEntCustomerFollowBizService;
import com.internetCafes.spms.web.customer.common.cont.CommonConst;
import com.internetCafes.spms.web.customer.common.cont.CustomerConst;
import com.internetCafes.spms.web.customer.common.util.UserInfoUtil;
import com.internetCafes.spms.web.customer.entity.customer.Customer;
import com.internetCafes.spms.web.customer.entity.customer.CustomerFollow;
import com.internetCafes.spms.web.customer.model.customer.CustomerDetailDo;
import com.internetCafes.spms.web.customer.model.customer.follow.CustomerFollowListRes;
import com.internetCafes.spms.web.customer.model.customer.follow.CustomerFollowSaveReq;
import com.internetCafes.spms.web.customer.model.customer.follow.CustomerFollowUpdateReq;
import com.internetCafes.spms.web.customer.model.role.RoleDeptDataDo;
import com.internetCafes.spms.web.customer.model.role.RoleDeptDataPo;
import com.internetCafes.spms.web.customer.model.user.EntUserEmployeeInfoListDo;
import com.internetCafes.spms.web.customer.model.user.EntUserEmployeeInfoListPo;
import com.internetCafes.spms.web.customer.service.customer.ICustomerFollowService;
import com.internetCafes.spms.web.customer.service.customer.ICustomerService;
import com.internetCafes.spms.web.customer.service.role.IRoleDeptDataAssoService;
import com.internetCafes.spms.web.customer.service.user.IEntUserInfoService;
import com.internetCafes.spms.web.sys.model.UserInfo;
import com.internetCafes.spms.web.tenant.model.podo.TenantDeptInfoPlusDo;
import com.internetCafes.spms.web.tenant.model.podo.TenantDeptInfoPlusPo;
import com.internetCafes.spms.web.tenant.service.ITenantDeptInfoPlusService;
import com.sms.common.util.hutool.core.bean.BeanUtil;
import com.sms.common.util.hutool.core.collection.CollectionUtil;
import com.sms.common.util.hutool.core.date.DatePattern;
import com.sms.common.util.hutool.core.date.DateUtil;
import com.sms.common.util.hutool.core.util.ObjectUtil;
import com.sms.common.util.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 客户跟进记录
 */
@Service
public class EntCustomerFollowBizServiceImpl implements IEntCustomerFollowBizService {

    @Autowired
    private ICustomerFollowService followService;
    @Autowired
    private ICustomerService customerService;
    @Autowired
    private ITenantDeptInfoPlusService tenantDeptInfoPlusService;
    @Autowired
    private ITenantDeptInfoPlusService deptInfoPlusService;
    @Autowired
    private IRoleDeptDataAssoService roleDeptDataAssoService;
    @Autowired
    private IEntUserInfoService userInfoService;

    @Override
    public boolean delete(Long id) {
        UserInfo userInfo = ShiroUtils.getUserEntity();
        if (ObjectUtil.isNotNull(userInfo.getManagerFlag()) && CommonConst.FlagEnum.NOT.getId().equals(userInfo.getManagerFlag())) {
            CustomerFollow followInfo = followService.getById(id);
            if (!followInfo.getCreateBy().equals(userInfo.getId())) {
                throw new RRException(RRExceptionCodeEnum.NO_AUTHORITY);
            }
        }
        return followService.removeById(id);
    }

    @Override
    public List<CustomerFollowListRes> list(Long customerId) {

        // 获取客户信息
        Customer customerPo = customerService.getById(customerId);

        List<CustomerFollowListRes> resList = new ArrayList<>();
        LambdaQueryWrapper<CustomerFollow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CustomerFollow::getCustomerId, customerId)
                .orderByDesc(CustomerFollow::getId);

        /*
         * 意向客户，只能看到自己的跟进日志
         * 普通客户，只能看到自己的跟进日志
         * 10-29
         */
        // 获取当前用户下部门以及父部门id列表
        UserInfo userEntity = ShiroUtils.getUserEntity();
        if (!UserInfoUtil.entSuperAdminJudge(userEntity)) {
            List<Long> deptChildIdList
                    = deptInfoPlusService.deptList(new TenantDeptInfoPlusDo().setMiddleDeptId(userEntity.getTenantDeptId()))
                    .stream().map(TenantDeptInfoPlusPo::getId)
                    .collect(Collectors.toList());
            List<Long> roleDataDeptIdList = roleDeptDataAssoService
                    .listPo(new RoleDeptDataDo().setUserId(userEntity.getId()))
                    .stream().map(RoleDeptDataPo::getDeptId).collect(Collectors.toList());
            deptChildIdList.addAll(roleDataDeptIdList);
            // deptChildIdList.removeIf(deptId -> deptId.equals(userEntity.getTenantDeptId()));
            List<Long> userIdList = new ArrayList<>();
            userIdList.add(userEntity.getId());
            if (CollectionUtil.isNotEmpty(deptChildIdList)) {
                List<EntUserEmployeeInfoListPo> userPoList = userInfoService.userEmployeeInfoListPo(new EntUserEmployeeInfoListDo().setDeptIdList(deptChildIdList));
                for (EntUserEmployeeInfoListPo userPo : userPoList) {
                    if (ObjectUtil.isNull(userPo.getDeptId())) {
                        continue;
                    }
                    if ( !roleDataDeptIdList.contains(userPo.getDeptId()) && !UserInfoUtil.managerJudge(userEntity)
                            && userPo.getDeptId().equals(userEntity.getTenantDeptId())
                            && CommonConst.FlagEnum.NOT.getId().equals(userPo.getManagerFlag())) {
                        continue;
                    }
                    userIdList.add(userPo.getId());
                }
            }
            queryWrapper.in(CustomerFollow::getCreateBy, userIdList);
        }

        List<CustomerFollow> followPoList = followService.list(queryWrapper);

        Long firstFollowId = null;

        if (CollectionUtil.isNotEmpty(followPoList)) {
            for (CustomerFollow po : followPoList) {
                CustomerFollowListRes res = new CustomerFollowListRes();
                BeanUtil.copyProperties(po, res);
                res.setCreateTime(DateUtil.format(po.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN))
                        .setUpdateAbleFlag(
                                po.getCreateBy().equals(ShiroUtils.getUserId()) && ObjectUtil.isNull(firstFollowId) ?
                                        CommonConst.FlagEnum.IS.getId() : CommonConst.FlagEnum.NOT.getId())
                        .setDeleteAbleFlag(po.getCreateBy().equals(ShiroUtils.getUserId()) ? CommonConst.FlagEnum.IS.getId() : CommonConst.FlagEnum.NOT.getId());
                firstFollowId = po.getId();
                resList.add(res);
            }
        }

        return resList;
    }

    @Override
    public boolean update(CustomerFollowUpdateReq req) {
        if (ObjectUtil.isNull(req.getId()) || StrUtil.isBlank(req.getContent())) {
            throw new RRException(RRExceptionCodeEnum.PARAM_ERROR);
        }

        // 跟进内容字数限制
        if (req.getContent().length() < CustomerConst.FOLLOW_CONTENT_LENGTH_LOWER) {
            throw new RRException(RRExceptionCodeEnum.CUSTOMER_FOLLOW_CONTENT_LOWER);
        }

        // 目前仅允许修改最后一条，并且需要是自己添加的才允许修改
        CustomerFollow followInfoPo = followService.getById(req.getId());
        if (ObjectUtil.isNull(followInfoPo)) {
            throw new RRException(RRExceptionCodeEnum.DATA_NOT_EXIST);
        }

        // 获取当前跟进记录的客户信息
        Customer customerPo = customerService.customerPoDetail(new CustomerDetailDo().setId(followInfoPo.getCustomerId()));
        if (ObjectUtil.isNull(customerPo)) {
            throw new RRException(RRExceptionCodeEnum.DATA_NOT_EXIST);
        }

        // 判断是否是最新一条记录
        List<CustomerFollow> followPoList = followService.list(new LambdaQueryWrapper<CustomerFollow>()
                .eq(CustomerFollow::getCustomerId, customerPo.getId()).orderByDesc(CustomerFollow::getId));

        CustomerFollow lastFollow = CollectionUtil.getFirst(followPoList);

        if (ObjectUtil.isNull(lastFollow) || !lastFollow.getId().equals(req.getId()) || !customerPo.getFollowUserId().equals(ShiroUtils.getUserId())
                || !lastFollow.getCreateBy().equals(ShiroUtils.getUserId())) {
            throw new RRException(RRExceptionCodeEnum.CUSTOMER_FOLLOW_CAN_NOT);
        }

        return followService.updateById(new CustomerFollow().setId(req.getId()).setContent(req.getContent()));
    }

    @Override
    public boolean save(CustomerFollowSaveReq req) {

        if (ObjectUtil.isNull(req.getCustomerId()) || StrUtil.isBlank(req.getContent())) {
            throw new RRException(RRExceptionCodeEnum.PARAM_ERROR);
        }

        // 跟进内容字数限制
        if (req.getContent().length() < CustomerConst.FOLLOW_CONTENT_LENGTH_LOWER) {
            throw new RRException(RRExceptionCodeEnum.CUSTOMER_FOLLOW_CONTENT_LOWER);
        }

        Customer customer = customerService.getById(req.getCustomerId());

        if (ObjectUtil.isNull(customer)) {
            throw new RRException(RRExceptionCodeEnum.DATA_NOT_EXIST);
        }

        /*
         * 跟进权限判断
         * 成交客户：无法跟进
         * 一般/意向客户：支持任何人跟进
         * 修改 by zj 2021-12-08
         * 成交客户：支持本人和上级人员跟进
         * 一般/意向客户：支持任何人跟进
         */
        UserInfo userEntity = ShiroUtils.getUserEntity();
        if (CustomerConst.TypeEnum.DEAL.getId().equals(customer.getTypeId())
                && !userEntity.getId().equals(customer.getFollowUserId())) {
            List<TenantDeptInfoPlusPo> deptList = tenantDeptInfoPlusService.parentDeptListByEmployeeUserId(userEntity.getId());
            List<Long> deptIdList = deptList.stream()
                    .map(TenantDeptInfoPlusPo::getId)
                    .collect(Collectors.toList());
            if (!deptIdList.contains(userEntity.getTenantDeptId())) {
                throw new RRException(RRExceptionCodeEnum.NO_AUTHORITY);
            }
        }

        CustomerFollow followDo = new CustomerFollow();
        followDo.setCustomerId(customer.getId()).setContent(req.getContent());
        return followService.save(followDo);

    }
}
